use std::collections::HashMap;

struct HashTable<K, V> {
    table: HashMap<K, V>,
}

impl<K, V> HashTable<K, V>
where
    K: std::cmp::Eq + std::hash::Hash,
{
    fn new() -> Self {
        HashTable {
            table: HashMap::new(),
        }
    }

    fn insert(&mut self, key: K, value: V) -> Option<V> {
        self.table.insert(key, value)
    }

    fn lookup(&self, key: &K) -> Option<&V> {
        self.table.get(key)
    }

    fn remove(&mut self, key: &K) -> Option<V> {
        self.table.remove(key)
    }

    fn num_entries(&self) -> usize {
        self.table.len()
    }
}

struct HashTableIterator<'a, K, V> {
    iter: std::collections::hash_map::Iter<'a, K, V>,
}

impl<'a, K, V> HashTableIterator<'a, K, V>
where
    K: std::cmp::Eq + std::hash::Hash,
{
    fn new(table: &'a HashTable<K, V>) -> Self {
        HashTableIterator {
            iter: table.table.iter(),
        }
    }

    fn has_next(&self) -> bool {
        self.iter.clone().count() > 0
    }

    fn next(&mut self) -> Option<(&K, &V)> {
        self.iter.next()
    }
}
